package com.yuanchu.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuanchu.common.utils.DateFormatUtils;
import com.yuanchu.common.utils.GoodsFormatUtils;
import com.yuanchu.common.utils.PageResult;
import com.yuanchu.common.utils.R;
import com.yuanchu.order.client.FeignMediaClient;
import com.yuanchu.order.client.FeignStoreClient;
import com.yuanchu.order.dao.YoshopOrderDao;
import com.yuanchu.order.dao.YoshopOrderRefundImageDao;
import com.yuanchu.order.dto.*;
import com.yuanchu.order.entity.*;
import com.yuanchu.order.searchconfig.MqOrderConstants;
import com.yuanchu.order.service.*;
import com.yuanchu.order.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@Service("yoshopOrderService")
public class YoshopOrderServiceImpl extends ServiceImpl<YoshopOrderDao, YoshopOrderEntity> implements YoshopOrderService {


    @Autowired
    private YoshopOrderDao orderMapper;

    @Resource
    private RestHighLevelClient client;
    @Resource
    private FeignStoreClient feignStoreClient;
    @Resource
    private YoshopOrderRefundImageDao orderRefundImageDao;
    @Resource
    private YoshopOrderRefundService orderRefundService;
    @Resource
    private YoshopOrderGoodsService orderGoodsService;
    @Resource
    private YoshopOrderAddressService orderAddressService;

    @Resource
    private FeignMediaClient feignMediaClient;
    @Resource
    private CheckoutOrderService checkoutOrderService;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private RedisUtils redisUtils;


    public TradeTrendVO getTradeTrend() {
        List<Map<String, Object>> trendList = orderMapper.getTradeTrendItems();
        // 初始化TradeTrendVO对象
        TradeTrendVO trend = new TradeTrendVO();
        List<String> dateList = new ArrayList<>();
        List<String> orderTotalList = new ArrayList<>();
        List<String> orderTotalPriceList = new ArrayList<>();
        // 初始化日期和数据列表
        for (int i = 6; i >= 0; i--) {
            String date = LocalDate.now().minusDays(i).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            dateList.add(date);
            orderTotalList.add("0");
            orderTotalPriceList.add(String.valueOf(BigDecimal.ZERO));
        }
        // 将查询结果填充到对应的位置
        for (Map<String, Object> map : trendList) {
            String date = String.valueOf(map.get("date"));
            int index = dateList.indexOf(date);
            if (index != -1) {
                orderTotalList.set(index, String.valueOf(map.get("orderTotal")));
                orderTotalPriceList.set(index, String.valueOf(map.get("orderTotalPrice")));
            }
        }
        trend.setDate(dateList);
        trend.setOrderTotal(orderTotalList);
        trend.setOrderTotalPrice(orderTotalPriceList);
        // Map<String, Object> resultMap = new HashMap<>();
        // resultMap.put("tradeTrend", trend);

        return trend;
    }


    @Override
    public List<YoshopOrderEntity> queryOrderSalesByMonth() {
        // 获取本月的订单量
        // 计算当前月份的第一天和最后一天
        LocalDate firstDayOfMonth = LocalDate.now().withDayOfMonth(1);
        LocalDate lastDayOfMonth = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
        // 转换为当前月份的Unix时间戳（精确到秒）
        long startTimestamp = firstDayOfMonth.atStartOfDay(ZoneOffset.UTC).toEpochSecond();
        long endTimestamp = lastDayOfMonth.atTime(23, 59, 59).atZone(ZoneOffset.UTC).toEpochSecond();
        LambdaQueryWrapper<YoshopOrderEntity> lqw = new LambdaQueryWrapper<>();
        lqw.between(YoshopOrderEntity::getCreateTime, startTimestamp, endTimestamp);
        List<YoshopOrderEntity> orders = this.list(lqw);
        return orders;
    }


    @Override
    public List<YoshopOrderEntity> queryOrderSalesByToday() {
        // 获取当天的订单量
        // 获取当前日期
        LocalDate today = LocalDate.now();
        // 当天开始时间（0点0分0秒）
        LocalDateTime startOfDay = today.atStartOfDay();
        long startTimestampInSeconds = startOfDay.toEpochSecond(ZoneOffset.UTC);
        // 当天结束时间（23点59分59秒）
        LocalDateTime endOfDay = today.atTime(23, 59, 59);
        long endTimestampInSeconds = endOfDay.toEpochSecond(ZoneOffset.UTC);
        return getOrderEntityList(startTimestampInSeconds, endTimestampInSeconds);
    }

    @Override
    public List<YoshopOrderEntity> queryOrderSalesByYesterday() {
        // 获取当前日期前一天的日期
        LocalDate yesterday = LocalDate.now().minus(1, ChronoUnit.DAYS);
        // 计算昨天开始时间（0点0分0秒）的时间戳
        LocalDateTime startOfYesterday = yesterday.atStartOfDay();
        long yesterdayStartInSeconds = startOfYesterday.toEpochSecond(ZoneOffset.UTC);
        // 计算昨天结束时间（23点59分59秒）的时间戳
        LocalDateTime endOfYesterday = yesterday.plusDays(1).atStartOfDay().minusSeconds(1);
        long yesterdayEndInSeconds = endOfYesterday.toEpochSecond(ZoneOffset.UTC);
        return getOrderEntityList(yesterdayStartInSeconds, yesterdayEndInSeconds);
    }

    private List<YoshopOrderEntity> getOrderEntityList(long startInSeconds, long endInSeconds) {
        LambdaQueryWrapper<YoshopOrderEntity> lqw = new LambdaQueryWrapper<>();
        lqw.eq(YoshopOrderEntity::getPayStatus, 20);
        lqw.between(YoshopOrderEntity::getCreateTime, startInSeconds, endInSeconds);
        return this.list(lqw);
    }

    @Override
    public Map<String, String> queryOrderStatistics() {
        List<YoshopOrderEntity> payOrderTotals = this.list();
        List<YoshopOrderEntity> collect = payOrderTotals.stream()
                .filter(order -> order.getPayStatus() == 20).collect(Collectors.toList());
        // 付款用户量
        List<Integer> payUserIds = collect.stream().map(YoshopOrderEntity::getUserId).distinct().collect(Collectors.toList());
        List<Integer> userIds = feignStoreClient.queryUserIds();
        // 判断两个list是否有相同的id，如果相同，count+1
        int consumeUserTotal = 0;
        for (Integer userId : payUserIds) {
            if (userIds.contains(userId)) {
                consumeUserTotal++;
            }
        }

        // 支付订单数
        int payOrders = collect.size();
        Map<String, String> map = new HashMap<>();
        // map.put("goodsTotal", String.valueOf(userIds.size()));
        map.put("userTotal", String.valueOf(userIds.size()));
        map.put("orderTotal", String.valueOf(collect.size()));
        map.put("consumeUserTotal", String.valueOf(consumeUserTotal));

        return map;
    }

    @Override
    public long queryOrderWaitSend() {
        LambdaQueryWrapper<YoshopOrderEntity> lqw = new LambdaQueryWrapper<>();
        lqw.eq(YoshopOrderEntity::getPayStatus, 20)
                .eq(YoshopOrderEntity::getDeliveryStatus, 10);
        return this.count(lqw);
    }

    @Override
    public long queryPendingOrder() {
        return this.count(new QueryWrapper<YoshopOrderEntity>().eq("pay_status", 10));
    }

    @Override
    public UserOrderCountsDto queryOrderCounts(int userId) {
        // String cacheKey = "user:orderCounts:" + userId;
        // if (redisUtils.hasKey(cacheKey)) {
        //     return (UserOrderCountsDto) redisUtils.get(cacheKey);
        // }
        // 查询用户订单
        List<YoshopOrderEntity> userOrders = this.list(new QueryWrapper<YoshopOrderEntity>()
                .eq("user_id", userId)
                .in("order_status", 10)
        );

        // 统计待发货订单 delivery_status 发货状态(10未发货 20已发货) && 付款状态(10未付款 20已付款)
        List<YoshopOrderEntity> payOrders = userOrders.stream().
                filter(order -> order.getPayStatus() == 20).collect(Collectors.toList());
        long deliveryOrders = payOrders.stream().filter(order -> order.getDeliveryStatus() == 10).count();
        // 统计待收货订单 receipt_status 收货状态(10未收货 20已收货)
        long receiptOrders = payOrders.stream()
                // .filter(order -> order.getOrderStatus() != 30)
                .filter(order -> order.getDeliveryStatus() == 20)
                .filter(order -> order.getReceiptStatus() == 10).count();
        // 统计待付款订单 pay_status 支付状态(10未付款 20已付款)
        long disPayOrders = userOrders.stream().filter(order -> order.getPayStatus() == 10).count();
        // 统计售后订单 refund_status 退款状态(10未退款 20已退款)
        List<YoshopOrderRefundEntity> orderRefunds = orderRefundService.list(new QueryWrapper<YoshopOrderRefundEntity>().eq("user_id", userId));
        long orderRefundTotal = orderRefunds.stream().filter(order -> order.getStatus() == 0).count();

        UserOrderCountsDto userOrderCounts = new UserOrderCountsDto();
        userOrderCounts.setDelivery((int) deliveryOrders);
        userOrderCounts.setReceived((int) receiptOrders);
        userOrderCounts.setPayment((int) disPayOrders);
        userOrderCounts.setRefund((int) orderRefundTotal);

        // 缓存
        // redisUtils.set(cacheKey, userOrderCounts);

        return userOrderCounts;
    }

    @Override
    public PageResult<OrderDetailDto> queryOrderList(String dataType, int page, Integer userId) {
        LambdaQueryWrapper<YoshopOrderEntity> lqw = new LambdaQueryWrapper<>();
        if (userId == null) {
            return null;
        }
        lqw.eq(YoshopOrderEntity::getUserId, userId);
        lqw.eq(YoshopOrderEntity::getIsDelete, 0);

        if ("payment".equals(dataType)) {
            lqw.eq(YoshopOrderEntity::getOrderStatus, 10);
            // 待支付
            lqw.eq(YoshopOrderEntity::getPayStatus, 10);
        } else if ("delivery".equals(dataType)) {
            lqw.eq(YoshopOrderEntity::getOrderStatus, 10);
            // 已支付
            lqw.eq(YoshopOrderEntity::getPayStatus, 20);
            // 待发货
            lqw.eq(YoshopOrderEntity::getDeliveryStatus, 10);
        } else if ("received".equals(dataType)) {
            lqw.eq(YoshopOrderEntity::getOrderStatus, 10);
            // 已发货
            lqw.eq(YoshopOrderEntity::getDeliveryStatus, 20);
            // 待收货
            lqw.eq(YoshopOrderEntity::getReceiptStatus, 10);
        } else if ("comment".equals(dataType)) {
            // 已完成
            lqw.eq(YoshopOrderEntity::getOrderStatus, 30);
            // 待评价
            lqw.eq(YoshopOrderEntity::getIsComment, 0);
        }
        lqw.orderByDesc(YoshopOrderEntity::getCreateTime);
        // 全部
        Page<YoshopOrderEntity> page1 = new Page<>(page, 15);
        Page<YoshopOrderEntity> page_result = this.page(page1, lqw);
        List<YoshopOrderEntity> records = page_result.getRecords();
        List<OrderDetailDto> orderList = records.stream()
                .map(item -> {
                    item.setCreateTime(DateFormatUtils.formatDatetime(item.getCreateTime()));
                    item.setGoods(queryOrderGoods(item.getOrderId(), userId));
                    Object updatePrice = item.getUpdatePrice();
                    Map<String, String> map = formatUpdatePrice(updatePrice.toString());
                    item.setUpdatePrice(String.valueOf(map));
                    setOrderStateText(item);
                    OrderDetailDto orderDetail = new OrderDetailDto();
                    BeanUtils.copyProperties(item, orderDetail);
                    return orderDetail;
                }).collect(Collectors.toList());

        return PageResult.formatPageResult(orderList, page, 15, page_result.getTotal());
    }

    @Override
    public OrderDetailDto getOrderDetailByOrderId(Integer orderId, Integer userId) {
        // order
        // 1、获取订单信息
        YoshopOrderEntity order = this.getById(orderId);
        if (order == null) {
            return null;
        }
        OrderDetailDto orderDetail = new OrderDetailDto();
        BeanUtils.copyProperties(order, orderDetail);
        // 根据订单id获取地址信息
        YoshopOrderAddressEntity orderAddress = orderAddressService.getAddressByOrderId(orderId);
        orderDetail.setAddress(orderAddress);
        // orderDetail.setCreateTime(DateFormatUtils.formatDatetime(order.getCreateTime()));
        // 获取订单关联商品信息
        orderDetail.setGoods(queryOrderGoods(orderId, userId));
        setOrderStateText(orderDetail);
        // update_price
        Object updatePrice = orderDetail.getUpdatePrice();
        Map<String, String> map = formatUpdatePrice(updatePrice.toString());
        orderDetail.setUpdatePrice(map);
        if (orderDetail.getPayStatus() == 20 && order.getDeliveryStatus() == 20){
            orderDetail.getGoods().forEach(item -> {
                if (item.getRefund() == null){
                    orderDetail.setIsAllowRefund(true);
                }
            });
        }
        // 2.setting
        // Map<String, Object> resultMap = new HashMap<>();
        // resultMap.put("order", orderDetail);
        // Map<String, Object> setting = new HashMap<>();
        // setting.put("points_name", "积分");
        // resultMap.put("setting", setting);
        return orderDetail;
    }


    private void setOrderStateText(YoshopOrderEntity order) {
        if (order.getPayStatus() == 10 && order.getOrderStatus() == 10) {
            order.setStateText("待支付");
        }
        if (order.getPayStatus() == 20 && order.getDeliveryStatus() == 10 && order.getOrderStatus() == 10) {
            order.setStateText("待发货");
        }
        if (order.getPayStatus() == 20 && order.getDeliveryStatus() == 20 && order.getReceiptStatus() == 10 && order.getOrderStatus() == 10) {
            order.setStateText("待收货");
        }
        if (order.getOrderStatus() == 30) {
            order.setStateText("已完成");
        }
        if (order.getOrderStatus() == 21) {
            order.setStateText("待取消");
        }
        if (order.getOrderStatus() == 20) {
            order.setStateText("已取消");
        }

    }

    public static Map<String, String> formatUpdatePrice(String updatePrice) {
        Map<String, String> map = new HashMap<>();
        BigDecimal decimal = new BigDecimal("0.00");
        BigDecimal decimal_price = new BigDecimal(updatePrice).setScale(2, BigDecimal.ROUND_HALF_UP);
        if (decimal.compareTo(decimal_price) < 0) {
            map.put("symbol", "-");
        } else {
            map.put("symbol", "+");
        }
        map.put("value", String.valueOf(decimal_price));
        return map;
    }

    // private List<YoshopOrderGoodsEntity> getOrderGoodsByOrderId(Integer orderId) {
    //     List<YoshopOrderGoodsEntity> orderGoodsEntities = orderGoodsService.list(new LambdaQueryWrapper<YoshopOrderGoodsEntity>()
    //             .eq(YoshopOrderGoodsEntity::getOrderId, orderId));
    //     orderGoodsEntities.forEach(goods -> {
    //         YoshopGoodsEntity goodsEntity = feignGoodsClient.queryGoodsBase(goods.getGoodsId());
    //         goods.setGoods(goodsEntity);
    //         // 解析商品属性
    //         String goodsProps = (String) goods.getGoodsProps();
    //         if (!StringUtils.isEmpty(goodsProps)){
    //             goods.setGoodsProps(getGoodsProps(goodsProps));
    //         }
    //     });
    //     return orderGoodsEntities;
    //
    // }

    /**
     * 解析商品属性
     *
     * @param props
     * @return
     */
    public List<Map<String, Object>> getGoodsProps(String props) {
        // 解析JSON数组到List<Map<String, Object>>
        JSONArray jsonArray = JSONArray.parseArray(props);
        if (StringUtils.isEmpty(props)) {
            return Collections.emptyList();
        }
        List<Map<String, Object>> specItemsAsMaps = new ArrayList<>();

        for (Object obj : jsonArray) {
            JSONObject jsonObject = (JSONObject) obj;
            Map<String, Object> itemMap = jsonObject.toJavaObject(Map.class);
            // 将嵌套的对象也转为Map
            Map<String, Object> groupMap = ((JSONObject) itemMap.get("group")).toJavaObject(Map.class);
            Map<String, Object> valueMap = ((JSONObject) itemMap.get("value")).toJavaObject(Map.class);

            // 将group和value替换为它们对应的Map对象
            itemMap.put("group", groupMap);
            itemMap.put("value", valueMap);

            specItemsAsMaps.add(itemMap);
        }
        return specItemsAsMaps;
    }

    /**
     * 根据订单id获取商品信息
     *
     * @param orderId
     * @return
     */
    public List<YoshopOrderGoodsEntity> queryOrderGoods(Integer orderId, Integer userId) {
        List<YoshopOrderGoodsEntity> orderGoodsEntities = orderGoodsService.list(
                new QueryWrapper<YoshopOrderGoodsEntity>().eq("order_id", orderId)
                        .eq("user_id", userId));
        orderGoodsEntities.forEach(goods -> {
            this.setGoodsProps(goods);
            goods.setRefund(orderRefundService.getRefund(orderId, goods.getOrderGoodsId()));
        });
        return orderGoodsEntities;
    }

    public List<YoshopOrderGoodsEntity> queryOrderGoodsByOrderId(Integer orderId) {
        List<YoshopOrderGoodsEntity> orderGoodsEntities = orderGoodsService.list(
                new QueryWrapper<YoshopOrderGoodsEntity>().eq("order_id", orderId));
        orderGoodsEntities.forEach(this::setGoodsProps);

        return orderGoodsEntities;
    }

    @Override
    public PageResult<OrderDetailDto> queryStoreOrderList(QueryOrderParamsDto param) {
        Integer searchType = param.getSearchType(); // 搜索类型
        Integer page = param.getPage(); // 页码
        String searchValue = param.getSearchValue();    // 搜索值
        Integer deliveryType = param.getDeliveryType(); // 物流方式
        Integer payType = param.getPayType();   // 支付方式
        long betweenTimeStart = convertStringToSeconds(param.getBetweenTimeStart());  // 时间区间
        long betweenTimeEnd = convertStringToSeconds(param.getBetweenTimeEnd());
        // 设置索引
        SearchRequest searchRequest = new SearchRequest("yuanchu");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        // 构建条件查询
        BoolQueryBuilder boolQueryBuilder = buildBasicQuery(param, searchType, searchValue, deliveryType, payType, betweenTimeStart, betweenTimeEnd);

        // 分页
        Integer pageNo = param.getPage();
        Integer pageSize = param.getPageSize();
        int start = (pageNo - 1) * pageSize;
        searchSourceBuilder.from(start);
        searchSourceBuilder.size(Math.toIntExact(pageSize));
        // 布尔查询
        searchSourceBuilder.query(boolQueryBuilder).sort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC));

        // 请求搜索
        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = null;
        try {
            searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("课程搜索异常：{}", e.getMessage());
            return PageResult.formatPageResult(Collections.emptyList(), pageNo, pageSize);
        }

        // 结果集处理
        SearchHits hits = searchResponse.getHits();
        SearchHit[] searchHits = hits.getHits();
        // 记录总数
        TotalHits totalHits = hits.getTotalHits();
        // 数据列表
        List<OrderDetailDto> list = new ArrayList<>();

        for (SearchHit hit : searchHits) {
            String sourceAsString = hit.getSourceAsString();
            OrderDetailDto orderDetail = JSON.parseObject(sourceAsString, OrderDetailDto.class);
            orderDetail.setCreateTime(DateFormatUtils.formatDatetime(orderDetail.getCreateTime()));
            orderDetail.setAddress(null);
            list.add(orderDetail);
        }
        return PageResult.formatPageResult(list, pageNo, pageSize, totalHits.value);
    }





    private static BoolQueryBuilder buildBasicQuery(QueryOrderParamsDto param, Integer searchType, String searchValue, Integer deliveryType, Integer payType, long betweenTimeStart, long betweenTimeEnd) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        // 关键字
        if (StringUtils.isNotEmpty(searchValue)) {
            // 搜索类型
            if (searchType == 10) {
                // 订单号
                boolQueryBuilder.must(QueryBuilders.matchQuery("orderNo", searchValue));
            } else if (searchType == 20) {
                // 会员昵称，匹配关键字
                boolQueryBuilder.must(QueryBuilders.matchQuery("user.nickName", searchValue));
            } else if (searchType == 30) {
                // 会员id
                boolQueryBuilder.must(QueryBuilders.termQuery("userId", searchValue));
            } else if (searchType == 40) {
                // 收货人姓名
                boolQueryBuilder.must(QueryBuilders.matchQuery("address.name", searchValue));
            } else if (searchType == 50) {
                // 收货人电话
                boolQueryBuilder.must(QueryBuilders.termQuery("address.phone", searchValue));
            }
        }
        // 过虑
        // 时间区间
        if (betweenTimeStart > 0 && betweenTimeEnd > 0) {
            RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("createTime");
            rangeQuery.lte(betweenTimeEnd);
            rangeQuery.gte(betweenTimeStart);
            boolQueryBuilder.filter(rangeQuery);
        }
        Integer orderSource = param.getOrderSource();   // 订单来源
        if (orderSource != null && orderSource > 0) {
            boolQueryBuilder.must(QueryBuilders.termQuery("orderSource", orderSource));
        }
        String dataType = param.getDataType();  // 订单类型
        // 判断订单类型
        if ("pay".equals(dataType)) {
            //  订单状态(10进行中、待支付
            boolQueryBuilder.must(QueryBuilders.termQuery("orderStatus", 10));
            boolQueryBuilder.must(QueryBuilders.termQuery("payStatus", 10));
        } else if ("delivery".equals(dataType)) {
            // 待发货 、已支付
            boolQueryBuilder.must(QueryBuilders.termQuery("payStatus", 20))
                    .must(QueryBuilders.termQuery("deliveryStatus", 10))
                    .mustNot(QueryBuilders.termQuery("orderStatus", 20));
        } else if ("receipt".equals(dataType)) {
            // 待收货、已发货
            boolQueryBuilder.must(QueryBuilders.termQuery("deliveryStatus", 20));
            boolQueryBuilder.must(QueryBuilders.termQuery("receiptStatus", 10));
        } else if ("complete".equals(dataType)) {
            // 已完成
            boolQueryBuilder.must(QueryBuilders.termQuery("orderStatus", 30));
        } else if ("cancel".equals(dataType)) {
            // 已取消
            boolQueryBuilder.must(QueryBuilders.termQuery("orderStatus", 20));
        }
        // 支付方式
        if (payType != null && payType > -1) {
            boolQueryBuilder.must(QueryBuilders.termQuery("payType", payType));
        }
        // 配送方式
        if (deliveryType != null && deliveryType != -1) {
            boolQueryBuilder.must(QueryBuilders.termQuery("deliveryType", deliveryType));
        }
        return boolQueryBuilder;
    }

    public YoshopOrderGoodsEntity queryOrderGoodsById(Integer orderGoodsId) {
        YoshopOrderGoodsEntity orderGoods = orderGoodsService.getById(orderGoodsId);
        setGoodsProps(orderGoods);
        // orderGoods.setCreateTime(DateFormatUtils.formatDatetime(orderGoods.getCreateTime()));
        return orderGoods;
    }

    @Override
    public boolean payOrderStatus(Integer userId, Integer orderId, Integer payType) {
        // 支付方式(10余额支付 20微信支付)
        if (payType == 10) {
            // 余额支付
            if (orderId == null) {
                return false;
            }
            YoshopOrderEntity orderEntity = this.getOne(new QueryWrapper<YoshopOrderEntity>()
                    .eq("order_id", orderId).eq("user_id", userId));
            if (orderEntity == null) {
                return false;
            }
            orderEntity.setPointsNum(0);
            checkoutOrderService.saveOrderPayMessage(userId, null, orderEntity, null);
            orderEntity.setPayStatus(20);
            orderEntity.setPayTime(String.valueOf(Instant.now().toEpochMilli() / 1000));
            orderEntity.setUpdateTime(String.valueOf(Instant.now().toEpochMilli() / 1000));
            return this.updateById(orderEntity);
        }
        return false;
    }

    @Override
    public boolean receiptOrder(Integer userId, Integer orderId) {
        // 订单状态(10进行中 20取消 21待取消 30已完成)
        YoshopOrderEntity orderEntity = this.getOne(new QueryWrapper<YoshopOrderEntity>().eq("order_id", orderId)
                .eq("user_id", userId));
        orderEntity.setOrderStatus(30);
        orderEntity.setReceiptStatus(20);
        orderEntity.setIsSettled(1);
        orderEntity.setUpdateTime(String.valueOf(Instant.now().toEpochMilli() / 1000));
        boolean update = this.updateById(orderEntity);
        if (!update) {
            return false;
        }
        // 发送消息更新索引
        rabbitTemplate.convertAndSend(MqOrderConstants.ORDER_EXCHANGE, MqOrderConstants.ORDER_INSERT_KEY, orderId);

        Integer pointsBonus = orderEntity.getPointsBonus();
        if (pointsBonus != null && pointsBonus > 0) {
            // 赠送积分
            R bonusPoints = feignStoreClient.bonusUserPoints(userId, orderEntity.getOrderNo(), pointsBonus, orderEntity.getStoreId());
            return bonusPoints.getCode() == 200;
        }
        return true;
    }


    @Override
    public OrderDetailDto getStoreOrderDetail(Integer orderId, Integer storeId) {
        // 2、从redis查询
        // String cacheKey = "order:" + orderId;
        // // 查询缓存
        // if (redisUtils.hasKey(cacheKey)) {
        //     return (OrderDetailDto) redisUtils.get(cacheKey);
        // }

        // 3、从数据库查询
        // 1、获取订单信息
        YoshopOrderEntity order = this.getById(orderId);
        if (order == null) {
            return null;
        }
        OrderDetailDto orderDetail = new OrderDetailDto();
        BeanUtils.copyProperties(order, orderDetail);
        // 根据订单id获取地址信息
        YoshopOrderAddressEntity orderAddress = orderAddressService.getAddressByOrderId(orderId);
        orderDetail.setAddress(orderAddress);
        // orderDetail.setCreateTime(DateFormatUtils.formatDatetime(order.getCreateTime()));
        // 获取订单关联商品信息
        orderDetail.setGoods(queryOrderGoodsByOrderId(orderId));
        setOrderStateText(orderDetail);
        orderDetail.setExpress(feignStoreClient.queryExpressById(orderDetail.getExpressId()));
        // update_price
        Object updatePrice = orderDetail.getUpdatePrice();
        Map<String, String> map = formatUpdatePrice(updatePrice.toString());
        orderDetail.setUpdatePrice(map);
        orderDetail.setUser(feignStoreClient.queryUserByUserId(order.getUserId()));
        orderDetail.setUpdateTime(DateFormatUtils.formatDatetime(orderDetail.getUpdateTime()));
        orderDetail.setDeliveryTime(DateFormatUtils.formatDatetime(orderDetail.getDeliveryTime()));
        orderDetail.setPayTime(DateFormatUtils.formatDatetime(orderDetail.getPayTime()));
        orderDetail.setReceiptTime(DateFormatUtils.formatDatetime(orderDetail.getReceiptTime()));
        // 更新缓存
        // redisUtils.set(cacheKey, orderDetail);

        return orderDetail;
    }

    /**
     * 批量添加es数据
     *
     * @param param
     * @return
     */
    @Override
    public PageResult<OrderDetailDto> geStoreOrderList(QueryOrderParamsDto param) {
        Integer orderSource = param.getOrderSource();   // 订单来源
        String dataType = param.getDataType();  // 订单类型
        Integer searchType = param.getSearchType(); // 搜索类型
        Integer page = param.getPage(); // 页码
        String searchValue = param.getSearchValue();    // 搜索值
        Integer deliveryType = param.getDeliveryType(); // 物流方式
        Integer payType = param.getPayType();   // 支付方式
        long betweenTimeStart = convertStringToSeconds(param.getBetweenTimeStart());  // 时间区间
        long betweenTimeEnd = convertStringToSeconds(param.getBetweenTimeEnd());
        LambdaQueryWrapper<YoshopOrderEntity> lqw = new LambdaQueryWrapper<>();
        lqw.eq(YoshopOrderEntity::getIsDelete, 0);
        // 订单来源
        if (orderSource != null && orderSource != -1) {
            lqw.eq(YoshopOrderEntity::getOrderSource, orderSource);
        }
        // 支付方式
        if (payType != null && payType != -1) {
            lqw.eq(YoshopOrderEntity::getPayType, payType);
        }
        // 配送方式
        if (deliveryType != null && deliveryType != -1) {
            lqw.eq(YoshopOrderEntity::getDeliveryType, deliveryType);
        }
        // 时间范围
        if (betweenTimeStart != 0 && betweenTimeEnd != 0) {
            lqw.between(YoshopOrderEntity::getCreateTime, betweenTimeStart, betweenTimeEnd);
            // lqw.gt(YoshopOrderEntity::getCreateTime, betweenTimeStart);
            // lqw.lt(YoshopOrderEntity::getCreateTime, betweenTimeEnd);
        }
        // 判断订单类型
        if ("pay".equals(dataType)) {
            lqw.eq(YoshopOrderEntity::getOrderStatus, 10);
            // 待支付
            lqw.eq(YoshopOrderEntity::getPayStatus, 10);
        } else if ("delivery".equals(dataType)) {
            // 已支付
            lqw.eq(YoshopOrderEntity::getPayStatus, 20);
            // 待发货
            lqw.eq(YoshopOrderEntity::getDeliveryStatus, 10);
        } else if ("receipt".equals(dataType)) {
            // 已发货
            lqw.eq(YoshopOrderEntity::getDeliveryStatus, 20);
            // 待收货
            lqw.eq(YoshopOrderEntity::getReceiptStatus, 10);
        } else if ("complete".equals(dataType)) {
            // 已完成
            lqw.eq(YoshopOrderEntity::getOrderStatus, 30);
        } else if ("cancel".equals(dataType)) {
            // 已取消
            lqw.eq(YoshopOrderEntity::getOrderStatus, 20);
        }
        // 判断搜索类型（10订单号、20会员昵称、30会员id、40收货人姓名、50收货人电话）
        if (searchType != null && searchType == 10 && StringUtils.isNotEmpty(searchValue)) {
            lqw.eq(YoshopOrderEntity::getOrderNo, searchValue);
        }
        lqw.orderByDesc(YoshopOrderEntity::getCreateTime);
        // 全部
        Page<YoshopOrderEntity> page1 = new Page<>(page, 40);
        Page<YoshopOrderEntity> pageResult = this.page(page1, lqw);
        List<YoshopOrderEntity> orderList = pageResult.getRecords();
        List<OrderDetailDto> orderDetailList = new ArrayList<>();
        for (YoshopOrderEntity order : orderList) {
            OrderDetailDto orderDetail = new OrderDetailDto();
            BeanUtils.copyProperties(order, orderDetail);
            // 根据订单id获取地址信息
            YoshopOrderAddressEntity orderAddress = orderAddressService.getAddressByOrderId(order.getOrderId());
            orderDetail.setAddress(orderAddress);
            // orderDetail.setCreateTime(DateFormatUtils.formatDatetime(order.getCreateTime()));
            // 获取订单关联商品信息
            orderDetail.setGoods(queryOrderGoodsByOrderId(order.getOrderId()));
            setOrderStateText(orderDetail);
            orderDetail.setExpress(feignStoreClient.queryExpressById(orderDetail.getExpressId()));
            // update_price
            Object updatePrice = orderDetail.getUpdatePrice();
            Map<String, String> map = formatUpdatePrice(updatePrice.toString());
            orderDetail.setUpdatePrice(map);
            orderDetail.setUser(feignStoreClient.queryUserByUserId(order.getUserId()));
            orderDetail.setUpdateTime(DateFormatUtils.formatDatetime(orderDetail.getUpdateTime()));
            orderDetail.setDeliveryTime(DateFormatUtils.formatDatetime(orderDetail.getDeliveryTime()));
            orderDetail.setPayTime(DateFormatUtils.formatDatetime(orderDetail.getPayTime()));
            orderDetail.setReceiptTime(DateFormatUtils.formatDatetime(orderDetail.getReceiptTime()));
            orderDetailList.add(orderDetail);
        }
        // 判断搜索类型（10订单号、20会员昵称、30会员id、40收货人姓名、50收货人电话）
        if (searchType != null && StringUtils.isNotEmpty(searchValue)) {
            orderDetailList = getYoshopOrderEntities(searchType, searchValue, orderDetailList);
            return PageResult.formatPageResult(orderDetailList, page, 10, orderDetailList.size());
        }
        return PageResult.formatPageResult(orderDetailList, page, 10, pageResult.getTotal());
    }


    private YoshopOrderAddressEntity getOrderAddress(Integer orderId, Integer storeId) {
        return orderAddressService.getOne(new LambdaQueryWrapper<YoshopOrderAddressEntity>()
                .eq(YoshopOrderAddressEntity::getOrderId, orderId)
                .eq(YoshopOrderAddressEntity::getStoreId, storeId)
        );
    }

    @Override
    @Transactional
    public void deliveryOrder(Integer storeId, OrderDeliveryParamsDto param) {
        Integer expressId = param.getForm().getExpressId();
        String expressNo = param.getForm().getExpressNo();
        Integer orderId = param.getOrderId();
        // 修改订单状态
        this.update(new UpdateWrapper<YoshopOrderEntity>()
                .eq("order_id", orderId)
                .set("express_id", expressId)
                .set("express_no", expressNo)
                .set("delivery_status", 20)
                .set("delivery_time", String.valueOf(Instant.now().toEpochMilli() / 1000))
                .set("update_time", String.valueOf(Instant.now().toEpochMilli() / 1000))
        );
        // 发送消息修改订单状态
        rabbitTemplate.convertAndSend(MqOrderConstants.ORDER_EXCHANGE, MqOrderConstants.ORDER_INSERT_KEY, orderId);
    }

    @Override
    public boolean deleteOrderById(Integer orderId, Integer storeId) {
        // 软删除订单
        boolean update = this.update(new UpdateWrapper<YoshopOrderEntity>().eq("order_id", orderId)
                .eq("store_id", storeId)
                .set("is_delete", 1));
        if (!update) {
            return false;
        }
        // 发送消息删除订单
        rabbitTemplate.convertAndSend(MqOrderConstants.ORDER_EXCHANGE, MqOrderConstants.ORDER_DELETE_KEY, orderId);
        return true;
    }

    @Override
    public boolean confirmCancerOrder(Integer orderId, Integer status, Integer storeId) {
        if (status == 1) {
            // 审核通过
            boolean update = this.update(new UpdateWrapper<YoshopOrderEntity>().eq("order_id", orderId)
                    .eq("store_id", storeId)
                    .set("order_status", 20)
                    .set("update_time", String.valueOf(Instant.now().toEpochMilli() / 1000))
            );
            if (!update) {
                return false;
            }
            // 发送消息修改订单状态
            rabbitTemplate.convertAndSend(MqOrderConstants.ORDER_EXCHANGE, MqOrderConstants.ORDER_INSERT_QUEUE, orderId);
            return true;
        }
        // 审核不通过
        boolean update = this.update(new UpdateWrapper<YoshopOrderEntity>().eq("order_id", orderId)
                .eq("store_id", storeId)
                .set("order_status", 10)
                .set("update_time", String.valueOf(Instant.now().toEpochMilli() / 1000))
        );
        if (!update) {
            return false;
        }
        rabbitTemplate.convertAndSend(MqOrderConstants.ORDER_EXCHANGE, MqOrderConstants.ORDER_INSERT_QUEUE, orderId);
        return true;
    }

    private static List<OrderDetailDto> getYoshopOrderEntities(Integer searchType, String searchValue, List<OrderDetailDto> orderList) {
        // 搜索类型
        if (searchType == 20) {
            // 会员昵称
            orderList = orderList.stream().filter(item -> item.getUser().getNickName().contains(searchValue)).collect(Collectors.toList());
        } else if (searchType == 30) {
            // 会员id
            orderList = orderList.stream().filter(item -> String.valueOf(item.getUserId()).equals(searchValue)).collect(Collectors.toList());
        } else if (searchType == 40) {
            // 收货人姓名
            orderList = orderList.stream().filter(item -> item.getAddress().getName().contains(searchValue)).collect(Collectors.toList());
        } else if (searchType == 50) {
            // 收货人电话
            orderList = orderList.stream().filter(item -> item.getAddress().getPhone().contains(searchValue)).collect(Collectors.toList());
        }
        return orderList;
    }


    public static long convertStringToSeconds(String dateString) {
        if (StringUtils.isEmpty(dateString)) {
            return 0;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        try {
            Date date = dateFormat.parse(dateString);
            return date.getTime() / 1000;
        } catch (Exception e) {
            // System.out.println("日期格式不正确：" + e.getMessage());
            return 0; // 返回0表示转换失败
        }
    }


    private static void determineOrderType(String dataType, LambdaQueryWrapper<YoshopOrderEntity> lqw) {
        if ("pay".equals(dataType)) {
            lqw.eq(YoshopOrderEntity::getOrderStatus, 10);
            // 待支付
            lqw.eq(YoshopOrderEntity::getPayStatus, 10);
        } else if ("delivery".equals(dataType)) {
            lqw.eq(YoshopOrderEntity::getOrderStatus, 10);
            // 已支付
            lqw.eq(YoshopOrderEntity::getPayStatus, 20);
            // 待发货
            lqw.eq(YoshopOrderEntity::getDeliveryStatus, 10);
        } else if ("receipt".equals(dataType)) {
            lqw.eq(YoshopOrderEntity::getOrderStatus, 10);
            // 已发货
            lqw.eq(YoshopOrderEntity::getDeliveryStatus, 20);
            // 待收货
            lqw.eq(YoshopOrderEntity::getReceiptStatus, 10);
        } else if ("complete".equals(dataType)) {
            // 已完成
            lqw.eq(YoshopOrderEntity::getOrderStatus, 30);
        } else if ("cancel".equals(dataType)) {
            // 已取消
            lqw.eq(YoshopOrderEntity::getOrderStatus, 20);
        }
    }


    @Override
    public boolean cancelOrder(Integer userId, Integer orderId) {
        YoshopOrderEntity orderEntity = this.getOne(new QueryWrapper<YoshopOrderEntity>()
                .eq("order_id", orderId).eq("user_id", userId));
        if (orderEntity == null) {
            return false;
        }
        orderEntity.setOrderStatus(21);
        orderEntity.setUpdateTime(String.valueOf(Instant.now().toEpochMilli() / 1000));
        boolean update = this.updateById(orderEntity);
        if (!update) {
            return false;
        }
        rabbitTemplate.convertAndSend(MqOrderConstants.ORDER_EXCHANGE, MqOrderConstants.ORDER_INSERT_KEY, orderId);
        return true;
    }


    private void setGoodsProps(YoshopOrderGoodsEntity orderGoods) {
        Object goodsProps = orderGoods.getGoodsProps();
        if (goodsProps != null) {
            List<Map<String, Object>> props = GoodsFormatUtils.formatGoodsProps(goodsProps.toString());
            orderGoods.setGoodsProps(props);
        }
        YoshopUploadFileEntity file = feignMediaClient.getUploadFileById(orderGoods.getImageId());
        if (file != null){
            orderGoods.setGoodsImage(file.getPreviewUrl());
        }
    }

    /**
     * 获取订单概览数据
     *
     * @return
     */
    public Overview queryOverview() {
        List<YoshopOrderEntity> salesByToday = this.queryOrderSalesByToday();
        List<YoshopOrderEntity> salesByYesterday = this.queryOrderSalesByYesterday();
        Overview overview = getOverview(salesByYesterday, salesByToday);
        return overview;
    }

    public Overview getOverview(List<YoshopOrderEntity> ydaOrders, List<YoshopOrderEntity> tdaOrders) {
        // 昨日数据 销售额 (元)
        BigDecimal priceYesterday = ydaOrders.stream().map(order -> new BigDecimal(order.getPayPrice()))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        // 昨日支付订单数
        long payOrdersYesterday = ydaOrders.stream().filter(order -> order.getPayStatus() == 20).count();
        // 昨日付款会员数
        long payUsersYesterday = ydaOrders.stream().filter(order -> order.getPayStatus() == 20)
                .map(YoshopOrderEntity::getUserId)
                .distinct().count();

        // 计算
        // 今日数据 销售额 (元)
        BigDecimal priceToday = tdaOrders.stream().map(order -> new BigDecimal(order.getPayPrice()))
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .setScale(2, RoundingMode.HALF_UP);
        // 今日付款会员数
        long payUsersToday = tdaOrders.stream().filter(order -> order.getPayStatus() == 20)
                .map(YoshopOrderEntity::getUserId)
                .distinct().count();
        // 今日支付订单数
        long payOrdersToday = tdaOrders.stream().filter(order -> order.getPayStatus() == 20).count();
        // 新增会员数
        Map<String, String> userByDay = feignStoreClient.queryNewUserByday();
        String userByToday = userByDay.get("tday");
        String userByYesterday = userByDay.get("ytd");
        return new Overview(
                priceYesterday, priceToday,
                payOrdersYesterday, payOrdersToday,
                userByYesterday, userByToday,
                payUsersYesterday, payUsersToday
        );
    }

    /**
     * 获取订单等待发货数据
     *
     * @return
     */
    public Map<String, String> queryPending() {
        // 获取订单等待发货数量
        long deliverOrderTotal = queryOrderWaitSend();
        // 售后单(笔)
        long refundTotal = orderRefundService.queryRefundOrder();
        // 待付款订单(笔)
        long paidOrderTotal = queryPendingOrder();
        Map<String, String> map = new HashMap<>();
        map.put("deliverOrderTotal", String.valueOf(deliverOrderTotal));
        map.put("refundTotal", String.valueOf(refundTotal));
        map.put("paidOrderTotal", String.valueOf(paidOrderTotal));
        return map;
    }


}